package com.github.limit.persistence;

import com.github.limit.entity.LimitData;
import org.springframework.context.annotation.Primary;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: wangdejun
 * @create: 2019-10-15 18:54
 **/
@Primary
public class MemoryAccessLimit extends AbstractAccessLimit {

    private static final Map<String, Map<String, Integer>> cacheMap = new ConcurrentHashMap<>(4);

    /**
     * 获取value
     *
     * @param prefixKey
     * @param key
     * @return
     */
    @Override
    public int doGetCount(String prefixKey, String key) {
        Map<String, Integer> map = cacheMap.get(prefixKey);
        map = Optional.ofNullable(map).orElse(new HashMap<>());
        Integer count = map.get(key);
        return Optional.ofNullable(count).orElse(0);
    }

    /**
     * 增加1
     *
     * @param prefixKey
     * @param key
     */
    @Override
    public void doIncrease(final String prefixKey, final String key) {
        String lockKey = prefixKey + ":" + key;
        synchronized (lockKey) {
            Map<String, Integer> map = cacheMap.get(prefixKey);
            /*if(map == null) {
                map = new HashMap<>();
            }*/
            map = Optional.ofNullable(map).orElse(new HashMap<>());
            Integer count = map.get(key);
            count = Optional.ofNullable(count).orElse(0);
            count++;
            map.put(key,count);
            cacheMap.put(prefixKey,map);

            /*Optional.ofNullable(map).map(m -> {
                Integer integer = m.get(key);
                integer = Optional.ofNullable(integer).orElse(0);
                integer++;
                cacheMap.get(prefixKey).put(key, integer);
                return null;
            }).orElseGet(() -> {
                Map<String, Integer> countMap = new HashMap<>();
                countMap.put(key, 1);
                cacheMap.put(prefixKey, countMap);
                return null;
            });*/
        }
    }

    /**
     * 根据前缀获取持久化的限流数据
     *
     * @param prefixKey
     * @return
     */
    @Override
    public List<LimitData> dataList(String prefixKey) {
        Map<String, Integer> countMap = cacheMap.get(prefixKey);
        List<LimitData> limitDataList = new ArrayList<>();
        if (countMap != null && !countMap.isEmpty()) {
            LimitData limitData;
            for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
                limitData = new LimitData(prefixKey + ":" + entry.getKey(), entry.getValue());
                limitDataList.add(limitData);
            }
        }
        return limitDataList;
    }
}
